package cn._2dland.util;

import java.util.BitSet;


public class URIEncoder {
	/** 16进制字符 */
	private static final String HEX_CHARS = "0123456789ABCDEF";

	/** 保留字符（不转码） */
	private static BitSet reservedChars = null;

	static {
		// 设置保留字符
		reservedChars = new BitSet(256);
		reservedChars.set('a', 'z' + 1);
		reservedChars.set('A', 'Z' + 1);
		reservedChars.set('0', '9' + 1);
		reservedChars.set('-');
		reservedChars.set('_');
		reservedChars.set('.');
		//reservedChars.set('!');
		reservedChars.set('~');
		//reservedChars.set('*');
		//reservedChars.set('\'');
		//reservedChars.set('(');
		//reservedChars.set(')');
	}

	/**
	 * 对字符串进行URI编码
	 * 
	 * @param content 要编码的内容
	 * @param charset 字符集
	 * 
	 * @return
	 */
	public static String encode(String content, String charset) {
		StringBuffer buf = new StringBuffer();
		for(int i = 0; i < content.length(); i++) {
			char ch = content.charAt(i);
			if(reservedChars.get(ch)) {
				buf.append(ch);
			} else {
				buf.append(encodeChar(ch, charset));
			}
		}

		return buf.toString();
	}

	/**
	 * 编码单个字符
	 * 
	 * @param ch
	 * @param charset
	 * 
	 * @return
	 */
	private static String encodeChar(char ch, String charset) {
		StringBuffer buf = new StringBuffer();
		if(ch < 256) {
			// 单字节字符
			buf.append("%25")
				.append(HEX_CHARS.charAt(ch >> 4 & 0x0F))
				.append(HEX_CHARS.charAt(ch & 0x0F));
		} else {
			// 多字节字符
			String s = String.valueOf(ch);
			byte[] b = null;
			try {
				b = s.getBytes(charset);
			} catch (Exception e) {
				b = s.getBytes();
			}
			
			for(int i=0; i<b.length; i++) {
				buf.append("%25")
					.append(HEX_CHARS.charAt(b[i] >> 4 & 0x0F))
					.append(HEX_CHARS.charAt(b[i] & 0x0F));
			}
		}

		return buf.toString();
	}
}
